package model
import(
	"time"
	"fmt"
	. "nightowl/logger"
)
type Time time.Time

const (
	PENDING = "PENDING"
	PUBLISHED = "PUBLISHED"
	OFFLINE = "OFFLINE"
)
const (
	INSTALLATION = "INSTALLATION"
	UNINSTALLATION = "UNINSTALLATION"
	UPGRADE = "UPGRADE"
)

const (
	SQL = "SQL"
)
const(
	FILE_TYPE_OTHER = "OTHER"
	FILE_TYPE_TPL = "TPL"
	FILE_TYPE_NACOS_CONFIG = "NACOS_CONFIG"
	FILE_TYPE_SQL = "SQL"
)


type EdgeClient struct{
	Id uint64 `yaml:"id" json:"id"`
	TenantId uint64 `yaml:"tenantId" json:"tenantId"`
	ResourcePoolId uint64 `yaml:"resourcePoolId" json:"resourcePoolId"`
	Name string `yaml:"name" json:"name"`
	Code string `yaml:"code" json:"code"`
	Server string `yaml:"server" json:"server"`
	Status string `yaml:"status" json:"status"`
	Loc string `yaml:"loc" json:"loc"`
	Note string `yaml:"note" json:"note"`
	LastActiveTime Time `yaml:"lastActiveTime" json:"lastActiveTime"`
	CreateUid uint64 `yaml:"createUid" json:"createUid"`
	CreateTime Time `yaml:"createTime" json:"createTime"`
	UpdateTime Time `yaml:"updateTime" json:"updateTime"`
	ResourcePool ResourcePool `yaml:"resourcePool" json:"resourcePool"`
}

type ResourcePool struct{
	Id uint64 `yaml:"id" json:"id"`
	Name string `yaml:"name" json:"name"`
	Code string `yaml:"code" json:"code"`
	Note string `yaml:"note" json:"note"`
	CreateUid uint64 `yaml:"createUid" json:"createUid"`
	CreateTime Time `yaml:"createTime" json:"createTime"`
	UpdateTime Time `yaml:"updateTime" json:"updateTime"`
}

type DeliveryHostGroup struct{
	Id uint64 `yaml:"id" json:"id"`
	TenantId uint64 `yaml:"tenantId" json:"tenantId"`
	DeliveryId uint64 `yaml:"deliveryId" json:"deliveryId"`
	GroupName string `yaml:"groupName" json:"groupName"`
	SuUsername string `yaml:"suUsername" json:"suUsername"`
	SuMethod string `yaml:"suMethod" json:"suMethod"`
	SuFlags string `yaml:"suFlags" json:"suFlags"`
	CreateUid uint64 `yaml:"createUid" json:"createUid"`
	CreateTime Time `yaml:"createTime" json:"createTime"`
	UpdateTime Time `yaml:"updateTime" json:"updateTime"`
}

type Task struct{
	Id uint64 `yaml:"id" json:"id"`
	TenantId uint64 `yaml:"tenantId" json:"tenantId"`
	Title string `yaml:"title" json:"title"`
	Del bool `yaml:"del" json:"del"`
	CreateUid uint64 `yaml:"createUid" json:"createUid"`
	CreateTime Time `yaml:"createTime" json:"createTime"`
	UpdateTime Time `yaml:"updateTime" json:"updateTime"`
	Note string `yaml:"note" json:"note"`
}

type TaskVer struct{
	Id uint64 `yaml:"id" json:"id"`
	TenantId uint64 `yaml:"tenantId" json:"tenantId"`
	TaskId uint64 `yaml:"taskId" json:"taskId"`
	Status string `yaml:"status" json:"status"`
	Version string `yaml:"version" json:"version"`
	Count int `yaml:"count" json:"count"`
	SuccessCount int `yaml:"successCount" json:"successCount"`
	FailCount int `yaml:"failCount" json:"failCount"`
	Del bool `yaml:"del" json:"del"`
	CreateUid uint64 `yaml:"createUid" json:"createUid"`
	Note string `yaml:"note" json:"note"`
	CreateTime Time `yaml:"createTime" json:"createTime"`
	UpdateTime Time `yaml:"updateTime" json:"updateTime"`
	Steps map[string][]TaskStep `yaml:"steps" json:"steps"`
	TaskRef Task `yaml:"taskRef" json:"taskRef"`
}

type Lib struct{
	Id uint64 `yaml:"id" json:"id"`
	TenantId uint64 `yaml:"tenantId" json:"tenantId"`
	Name string `yaml:"name" json:"name"`
	Type string `yaml:"type" json:"type"`
	Status string `yaml:"status" json:"status"`
	Del bool `yaml:"del" json:"del"`
	Note string `yaml:"note" json:"note"`
	CreateUid uint64 `yaml:"createUid" json:"createUid"`
	CreateTime Time `yaml:"createTime" json:"createTime"`
	UpdateTime Time `yaml:"updateTime" json:"updateTime"`
}

type LibMethodArg struct{
	Name string `yaml:"name" json:"name"`
	Note string `yaml:"note" json:"note"`
	Optional bool `yaml:"optional" json:"optional"`
}

type LibMethodReturn struct{
	Note string `yaml:"note" json:"note"`
}

type LibMethod struct{
	Id uint64 `yaml:"id" json:"id"`
	TenantId uint64 `yaml:"tenantId" json:"tenantId"`
	LibVerId uint64 `yaml:"libVerId" json:"libVerId"`
	Name string `yaml:"name" json:"name"`
	Status string `yaml:"status" json:"status"`
	Ret LibMethodReturn `yaml:"ret" json:"ret"`
	Args []LibMethodArg `yaml:"args" json:"args"`
	Note string `yaml:"note" json:"note"`
	CreateUid uint64 `yaml:"createUid" json:"createUid"`
	CreateTime Time `yaml:"createTime" json:"createTime"`
	UpdateTime Time `yaml:"updateTime" json:"updateTime"`
}

type LibVer struct{
	Id uint64 `yaml:"id" json:"id"`
	TenantId uint64 `yaml:"tenantId" json:"tenantId"`
	LibId uint64 `yaml:"libId" json:"libId"`
	Version string `yaml:"version" json:"version"`
	Status string `yaml:"status" json:"status"`
	Shell string `yaml:"shell" json:"shell"`
	Del bool `yaml:"del" json:"del"`
	Note string `yaml:"note" json:"note"`
	CreateUid uint64 `yaml:"createUid" json:"createUid"`
	CreateTime Time `yaml:"createTime" json:"createTime"`
	UpdateTime Time `yaml:"updateTime" json:"updateTime"`
	Files []DeployFile `yaml:"files" json:"files"`
	Methods []LibMethod `yaml:"methods" json:"methods"`
	LibRef Lib `yaml:"libRef" json:"libRef"`
	Dependencies []LibVer `yaml:"dependencies" json:"dependencies"`
}

type TaskVar struct{
	Id uint64 `yaml:"id" json:"id"`
	TenantId uint64 `yaml:"tenantId" json:"tenantId"`
	Sort int `yaml:"sort" json:"sort"`
	TaskVerId uint64 `yaml:"taskVerId" json:"taskVerId"`
	Title string `yaml:"title" json:"title"`
	StepId uint64 `yaml:"stepId" json:"stepId"`
	Tag string `yaml:"tag" json:"tag"`
	InoutType string `yaml:"inoutType" json:"inoutType"`
	Key string `yaml:"key" json:"key"`
	Val string `yaml:"val" json:"val"`
	ValType string `yaml:"valType" json:"valType"`
	ValOptions []map[string]string `yaml:"valOptions" json:"valOptions"`
	Del bool `yaml:"del" json:"del"`
	Note string `yaml:"note" json:"note"`
	CreateUid uint64 `yaml:"createUid" json:"createUid"`
	CreateTime Time `yaml:"createTime" json:"createTime"`
	UpdateTime Time `yaml:"updateTime" json:"updateTime"`
}

type DeployFile struct{
	Id uint64 `yaml:"id" json:"id"`
	TenantId uint64 `yaml:"tenantId" json:"tenantId"`
	Name string `yaml:"name" json:"name"`
	Status string `yaml:"status" json:"status"`
	Ext string `yaml:"ext" json:"ext"`
	Mimetype string `yaml:"mimetype" json:"mimetype"`
	Version string `yaml:"version" json:"version"`
	DirId uint64 `yaml:"dirId" json:"dirId"`
	Size uint64 `yaml:"size" json:"size"`
	Sign string `yaml:"sign" json:"sign"`
	Url string `yaml:"url" json:"url"`
	Del bool `yaml:"del" json:"del"`
	Content string `yaml:"content" json:"content"`
	Note string `yaml:"note" json:"note"`
	CreateUid uint64 `yaml:"createUid" json:"createUid"`
	CreateTime Time `yaml:"createTime" json:"createTime"`
	UpdateTime Time `yaml:"updateTime" json:"updateTime"`
}

type TaskFile struct{
	Id uint64 `yaml:"id" json:"id"`
	TenantId uint64 `yaml:"tenantId" json:"tenantId"`
	Sort int `yaml:"sort" json:"sort"`
	TaskVerId uint64 `yaml:"taskVerId" json:"taskVerId"`
	StepId uint64 `yaml:"stepId" json:"stepId"`
	Name string `yaml:"name" json:"name"`
	Version string `yaml:"version" json:"version"`
	Key string `yaml:"key" json:"key"`
	FileType string `yaml:"fileType" json:"fileType"`
	Fid uint64 `yaml:"fid" json:"fid"`
	Url string `yaml:"url" json:"url"`
	Dir string `yaml:"dir" json:"dir"`
	Del bool `yaml:"del" json:"del"`
	Note string `yaml:"note" json:"note"`
	CreateUid uint64 `yaml:"createUid" json:"createUid"`
	CreateTime Time `yaml:"createTime" json:"createTime"`
	UpdateTime Time `yaml:"updateTime" json:"updateTime"`
	Ref DeployFile `yaml:"ref" json:"ref"`
}

type TaskStep struct{
	Id uint64 `yaml:"id" json:"id"`
	TenantId uint64 `yaml:"tenantId" json:"tenantId"`
	Sort int `yaml:"sort" json:"sort"`
	TaskVerId uint64 `yaml:"taskVerId" json:"taskVerId"`
	Title string `yaml:"title" json:"title"`
	HostGroup string `yaml:"hostGroup" json:"hostGroup"`
	TaskType string `yaml:"taskType" json:"taskType"`
	ActionType string `yaml:"actionType" json:"actionType"`
	Cmd string `yaml:"cmd" json:"cmd"`
	Files []TaskFile `yaml:"files" json:"files"`
	Vars []TaskVar `yaml:"vars" json:"vars"`
	DependLibs []LibVer `yaml:"dependLibs" json:"dependLibs"`
	Del bool `yaml:"del" json:"del"`
	Note string `yaml:"note" json:"note"`
	CreateUid uint64 `yaml:"createUid" json:"createUid"`
	CreateTime Time `yaml:"createTime" json:"createTime"`
	UpdateTime Time `yaml:"updateTime" json:"updateTime"`
}

type DeliveryStep struct{
	Id uint64 `yaml:"id" json:"id"`
	TenantId uint64 `yaml:"tenantId" json:"tenantId"`
	DeliveryId uint64 `yaml:"deliveryId" json:"deliveryId"`
	TaskVerId uint64 `yaml:"taskVerId" json:"taskVerId"`
	TaskStepId uint64 `yaml:"taskStepId" json:"taskStepId"`
	Status string `yaml:"status" json:"status"`
	TaskType string `yaml:"taskType" json:"taskType"`
	Sort int `yaml:"sort" json:"sort"`
	Snapshot TaskStep `yaml:"snapshot" json:"snapshot"`
	Note string `yaml:"note" json:"note"`
	CreateUid uint64 `yaml:"createUid" json:"createUid"`
	CreateTime Time `yaml:"createTime" json:"createTime"`
	UpdateTime Time `yaml:"updateTime" json:"updateTime"`
}

type DeliveryTask struct{
	Id uint64 `yaml:"id" json:"id"`
	TenantId uint64 `yaml:"tenantId" json:"tenantId"`
	DeliveryId uint64 `yaml:"deliveryId" json:"deliveryId"`
	TaskVerId uint64 `yaml:"taskVerId" json:"taskVerId"`
	DependTaskVerIds []uint64 `yaml:"dependTaskVerIds" json:"dependTaskVerIds"`
	Optional bool `yaml:"optional" json:"optional"`
	Status string `yaml:"status" json:"status"`
	Enabled bool `yaml:"enabled" json:"enabled"`
	Sort int `yaml:"sort" json:"sort"`
	Note string `yaml:"note" json:"note"`
	Steps map[string][]DeliveryStep `yaml:"steps" json:"steps"`
	CreateUid uint64 `yaml:"createUid" json:"createUid"`
	CreateTime Time `yaml:"createTime" json:"createTime"`
	UpdateTime Time `yaml:"updateTime" json:"updateTime"`
	Ref TaskVer `yaml:"ref" json:"ref"`
}

type DeliveryVar struct{
	Id uint64 `yaml:"id" json:"id"`
	TenantId uint64 `yaml:"tenantId" json:"tenantId"`
	DeliveryId uint64 `yaml:"deliveryId" json:"deliveryId"`
	TaskVerId uint64 `yaml:"taskVerId" json:"taskVerId"`
	TaskVarId uint64 `yaml:"taskVarId" json:"taskVarId"`
	Key string `yaml:"key" json:"key"`
	Val string `yaml:"val" json:"val"`
	Sort int `yaml:"sort" json:"sort"`
	Note string `yaml:"note" json:"note"`
	CreateUid uint64 `yaml:"createUid" json:"createUid"`
	CreateTime Time `yaml:"createTime" json:"createTime"`
	UpdateTime Time `yaml:"updateTime" json:"updateTime"`
}

type DeliveryHostUser struct{
	Username string `yaml:"username" json:"username"`
	Pwd string `yaml:"pwd" json:"pwd"`
}

type DeliveryHost struct{
	Id uint64 `yaml:"id" json:"id"`
	TenantId uint64 `yaml:"tenantId" json:"tenantId"`
	DeliveryId uint64 `yaml:"deliveryId" json:"deliveryId"`
	Hostname string `yaml:"hostname" json:"hostname"`
	Ipv4 string `yaml:"ipv4" json:"ipv4"`
	Ipv6 string `yaml:"ipv6" json:"ipv6"`
	SshPort int `yaml:"sshPort" json:"sshPort"`
	SshUsername string `yaml:"sshUsername" json:"sshUsername"`
	SshPwd string `yaml:"sshPwd" json:"sshPwd"`
	Users []DeliveryHostUser `yaml:"users" json:"users"`
	Groups []string `yaml:"groups" json:"groups"`
	Del bool `yaml:"del" json:"del"`
	Note string `yaml:"note" json:"note"`
	CreateUid uint64 `yaml:"createUid" json:"createUid"`
	CreateTime Time `yaml:"createTime" json:"createTime"`
	UpdateTime Time `yaml:"updateTime" json:"updateTime"`
}

type Delivery struct{
	Id uint64 `yaml:"id" json:"id"`
	TenantId uint64 `yaml:"tenantId" json:"tenantId"`
	PipelineVerId uint64 `yaml:"pipelineVerId" json:"pipelineVerId"`
	ResourcePoolId uint64 `yaml:"resourcePoolId" json:"resourcePoolId"`
	EdgeClientId uint64 `yaml:"edgeClientId" json:"edgeClientId"`
	Tag string `yaml:"tag" json:"tag"`
	Title string `yaml:"title" json:"title"`
	Status string `yaml:"status" json:"status"`
	TaskType string `yaml:"taskType" json:"taskType"`
	Del bool `yaml:"del" json:"del"`
	Note string `yaml:"note" json:"note"`
	CreateUid uint64 `yaml:"createUid" json:"createUid"`
	CreateTime Time `yaml:"createTime" json:"createTime"`
	UpdateTime Time `yaml:"updateTime" json:"updateTime"`
	Hosts []DeliveryHost `yaml:"hosts" json:"hosts"`
	Vars []DeliveryVar `yaml:"vars" json:"vars"`
	Tasks []DeliveryTask `yaml:"tasks" json:"tasks"`
	HostGroups []DeliveryHostGroup `yaml:"hostGroups" json:"hostGroups"`
	ResourcePool ResourcePool `yaml:"resourcePool" json:"resourcePool"`
	EdgeClient EdgeClient `yaml:"edgeClient" json:"edgeClient"`
	Libs []LibVer `yaml:"libs" json:"libs"`
}


/****************任务执行编排 START********************/
const(
	TASK_RUN_STATUS_PENDING = "PENDING"
	TASK_RUN_STATUS_SUCCESS = "SUCCESS"
	TASK_RUN_STATUS_RUNNING = "RUNNING"
	TASK_RUN_STATUS_ERROR = "ERROR"
	TASK_RUN_STATUS_CANCELED = "CANCELED"	
)
type SuUser struct{
	Username string
	Pwd string
	Method string
	Flags string
}
type TaskRun struct{
	Status string
	Dependencies []*TaskRun
	StepRuns []*TaskStepRun
	TaskDir string
	DeliveryTaskId uint64
	TaskVerId uint64
	HostFile string
}
type TaskStepRun struct{
	Status string
	StepDir string
	TplDir string
	BuildDir string
	Entrypoint string
	DirName string
	StepId uint64
	DeliveryStepId uint64
	PlaybookDir string
	PlaybookFile string
	RemoteShellDir string
	RemoteShellFile string 
	HostGroup string
	User *DeliveryHostUser
	SuUser *SuUser
	LogFile string
	Logger *Logger
}
type RunVar struct{
	Key string
	Val interface{}
}


/****************任务执行编排 END********************/
/****************Ansible 模版渲染 START********************/
type WorkEnv struct{
	WorkDir string
	TplDir string
	BuildDir string
	HostFile string
}
type AnsiHostGroup struct{
	Name string
	Hosts []*AnsiHost
	User *DeliveryHostUser
	SuUser *SuUser
}
type AnsiHost struct{
	Ipv4 string
	Port int
	User *DeliveryHostUser
	SuUser *SuUser
}
/****************Ansible 模版渲染 END********************/
const (
    timeFormart = "2006-01-02 15:04:05"
)

func (t *Time) UnmarshalJSON(data []byte) (err error) {
    now, err := time.ParseInLocation(`"`+timeFormart+`"`, string(data), time.Local)
    if err != nil{
    	fmt.Println("UnmarshalJSON xxxx:", data, now, err,"Time:")
    }
    *t = Time(now)
    return
}
func (t Time) MarshalJSON() ([]byte, error) {
    formatted := `"` + time.Time(t).Format(timeFormart) + `"`
    return []byte(formatted), nil
}
func (t *Time) UnmarshalYAML(unmarshal func(interface{}) error) error {
	
	var data string
	err := unmarshal(&data)
	if err != nil {
		return nil
	}

	now, err := time.Parse(timeFormart, data)
	*t = Time(now)
	// fmt.Println("UnmarshalYAML xxxx:", data, now, err,"Time:",*t)
    return nil
}
func (t Time) MarshalYAML() (interface{}, error) {
    // fmt.Println("MarshalYAML xxxx:", t, time.Now())
    return time.Time(t).Format(timeFormart), nil
}
